home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1996 November / macformat-043.iso / mac / Shareware Plus / Developers / Sprite Animation Toolkit 2.3.8 / Add-ons / Storage / Preferences.p next >
Encoding:
Text File  |  1996-05-23  |  6.8 KB  |  237 lines  |  [TEXT/PJMM]

  1. {Preferences file handling}
  2.  
  3. {Principle: If we can write in the app itself, we do, but if not, or if there is already}
  4. {a prefs file, we use a pref file in the system folder. (The idea is that it is very elegant}
  5. {to save prefs in the application, whenever that is allowable.)}
  6.  
  7. {New version (march -94), stand-alone, takes file name and type as parameters,}
  8. {can be forced to create a pref file, includes resource copying routine.}
  9. {Newer, summer -95: no globals. Cleaned up some more.}
  10.  
  11. {What can we improve? Check the "shared" flag and set alwaysExternal if it is set?}
  12.  
  13. unit Preferences;
  14.  
  15. {Special thanks to Peter Lewis, who made and released source-code to DeHQX v2.0.0 © Peter Lewis, Aug 1991 }
  16.  
  17. interface
  18.  
  19. {$IFC UNDEFINED THINK_PASCAL}
  20.     uses
  21.         Types, QuickDraw, Fonts, Events, Packages, Menus, Dialogs, Windows,{}
  22.         OSUtils, ToolUtils, Resources, Folders, Files, Memory, Errors;
  23. {$ENDC}
  24.  
  25.     function SetPrefFile (prefsFileName: Str255; prefCreator, prefType: OSType; var appFile, prefFile: Integer; alwaysExternal: Boolean): Boolean;
  26. {Open the pref file if needed. Return the variables appFile and prefFile.}
  27. {If alwaysExternal is true, we always want a pref file in the system folder even if we can save in the application.}
  28. {Returns true if a new prefFile was created.}
  29.  
  30. {Copy a resource from one file to another. Useful when SetPrefFile returns true!}
  31.     function CopyResource (fromFile, toFile: integer; theResType: ResType; id: integer): OSErr;
  32.  
  33. implementation
  34.  
  35. { 1) Find the Preferences folder}
  36. { 2) Kolla om prefsfil existerar. I så fall, öppna den och gå till 6. }
  37. { 3) Get a resource and change it with ChangeResource. If it worked, go to 6.}
  38. { 4) Create a pref file and open it.}
  39. { 5) Get resources from the app and copy to the pref file.}
  40. { 6) Get resources, create if they don't exist.}
  41.  
  42.     var
  43.         sysEnv: SysEnvRec;
  44.  
  45. {$IFC UNDEFINED THINK_PASCAL}
  46. {$ELSEC}
  47.     const
  48. { From Folders:}
  49.         kPreferencesFolderType = 'pref';        {preferences for applications go here}
  50.  
  51. { From Folders:}
  52.     function FindFolder (vRefNum: INTEGER; folderType: OSType; createFolder: BOOLEAN; var foundVRefNum: INTEGER; var foundDirID: LONGINT): OSErr;
  53.     inline
  54.         $7000, $A823;
  55. {$ENDC}
  56.  
  57.     function GetDirID (wdrn: integer; var vrn: integer; var dirID: longInt): OSErr;
  58.         var
  59.             procID: longInt;
  60.             oe: OSErr;
  61.     begin
  62.         oe := GetWDInfo(wdrn, vrn, dirID, procID);
  63.         if oe <> noErr then
  64.             begin
  65.                 vrn := wdrn;
  66.                 dirID := 0;
  67.             end;
  68.         GetDirID := oe;
  69.     end;
  70.  
  71.     function GetPrefsFolder (var ovrn: integer): OSErr;
  72.         var
  73.             vrn: integer;
  74.             sDirID: longint;
  75.             oe: OSErr;
  76.             pb: WDPBRec;
  77.             oDirID: longint; {förr var-deklarerad utvariabel}
  78.             oVolID: integer;{förr var-deklarerad utvariabel}
  79.     begin
  80.         vrn := sysEnv.sysVRefNum;
  81.         if sysEnv.systemVersion >= $0700 then {System7}
  82.             begin
  83.                 sDirID := 0;
  84.                 oe := GetDirID(vrn, vrn, sDirID);
  85.                 oe := FindFolder(vrn, kPreferencesFolderType, true, oVolID, oDirID);
  86.  
  87. {Convert FindFolders volref+dirid to WDref}
  88.                 pb.ioVRefNum := oVolID;
  89.                 pb.ioWDProcID := longint('ERIK');
  90.                 pb.ioWDDirID := oDirID;
  91.                 pb.ioWDIndex := 0;
  92.                 pb.ioNamePtr := nil;
  93.                 pb.ioCompletion := nil;
  94. {$IFC UNDEFINED THINK_PASCAL}
  95.                 oe := PBOpenWDSync(@pb);
  96. {$ELSEC}
  97.                 oe := PBOpenWD(@pb, false);
  98. {$ENDC}
  99.                 ovrn := pb.ioVRefNum; {WDRefNum}
  100.             end
  101.         else
  102.             begin
  103.                 ovrn := vrn;
  104.                 oe := NoErr;
  105.             end;
  106.         GetPrefsFolder := oe;
  107.     end;
  108.  
  109.     function SetPrefFile (prefsFileName: Str255; prefCreator, prefType: OSType; var appFile, prefFile: Integer; alwaysExternal: Boolean): Boolean;
  110.         var
  111.             err: OSErr;
  112.             prefsFolder: integer;
  113.             h: handle;
  114.             s: str255;
  115.     begin
  116.         err := SysEnvirons(1, sysEnv);
  117.         appFile := CurResFile; {save the resfile of the app}
  118.         prefFile := 0;
  119.         SetPrefFile := false;
  120. { 1) Find Preferencefolder}
  121.         err := GetPrefsFolder(prefsFolder);
  122.         if err <> NoErr then
  123.             ;
  124. {ReportStr('Error finding system folder.')}
  125.  
  126. { 2) If preffile exists, open it and go to 6. }
  127.         prefFile := OpenRFPerm(prefsFileName, prefsFolder, FSRdWrPerm);
  128.         if ResError = noErr then
  129.             begin
  130. {Consider checking preffile versionnumber!}
  131.             end
  132.         else
  133.             begin
  134.                 prefFile := 0;
  135.  
  136. { 3) Get a resource and change it with ChangeResource. If it worked, go to 6.}
  137. {If alwaysExternal is true, we don't have to check.}
  138.                 if not alwaysExternal then
  139.                     begin
  140.                         h := Get1Resource(prefCreator, 0); {The program always has a signature if it has a BNDL.}
  141.                         if h = nil then
  142.                             begin
  143. {ReportStr('Resource missing!');}
  144.                             end;
  145.                         ChangedResource(h);
  146.                         alwaysExternal := ResError <> noErr; {Note that alwaysExternal is changed here to signal the descision to create a new pref file!}
  147.                         ReleaseResource(h); {Done with the resource}
  148.                     end;
  149.  
  150.                 if alwaysExternal then
  151.                     begin
  152. { 4) Create a pref file and open it.}
  153.                         err := Create(PrefsFileName, PrefsFolder, PrefCreator, PrefType);
  154.                         if err = noErr then
  155.                             begin
  156.                                 HCreateResFile(PrefsFolder, 0, PrefsFileName);
  157.                                 if ResError <> noErr then
  158.                                     begin
  159. {ReportStr('Couldn''t create resource fork!');}
  160.                                     end
  161.                                 else
  162.                                     prefFile := OpenRFPerm(PrefsFileName, PrefsFolder, FSRdWrPerm);
  163.  
  164.                                 if ResError = noErr then
  165.                                     SetPrefFile := true; {new pref file!}
  166. { 5) Get resources from the app and copy to the pref file.}
  167. {Done by your app when SetPrefFile returns true!}
  168.                             end{Create succeded}
  169.                         else
  170. {ReportStr('Failed to create prefsfile!')}
  171.                             ;
  172.                     end; {App write protected.}
  173.             end; {Pref file didn't exist}
  174. { 6) Get resources, create if they don't exist.}
  175. {Done by your app.}
  176.     end; {SetPrefFile}
  177.  
  178.  
  179. {Copy resource:}
  180.     function CopyResource (fromFile, toFile: integer; theResType: ResType; id: integer): OSErr;
  181.         var
  182.             oldResFile: integer;
  183.             res, rescopy: Handle;
  184.             wasLoaded: Boolean;
  185.             theID: integer;
  186.             theType: ResType;
  187.             theName: Str255;
  188.         procedure Barf;
  189.         begin
  190.             CopyResource := ResError;
  191.             UseResFile(oldResFile); {restore}
  192.             exit(CopyResource);
  193.         end;
  194.         procedure CheckError;
  195.         begin
  196.             if ResError <> noErr then
  197.                 Barf;
  198.         end; {CheckError}
  199.     begin
  200.         oldResFile := CurResFile;
  201.         UseResFile(fromFile);
  202.         CheckError;
  203.  
  204.         SetResLoad(false);
  205.         res := Get1Resource(theResType, id);
  206. {CheckError doesn't work here, since we always must do SetResLoad(true)!!!}
  207.         SetResLoad(true);
  208.         CheckError;
  209.         if res <> nil then
  210.             begin
  211.                 wasLoaded := res^ = nil;
  212.                 LoadResource(res);
  213.                 CheckError;
  214.                 UseResFile(toFile);
  215.                 CheckError;
  216.                 GetResInfo(res, theID, theType, theName);
  217.                 CheckError;
  218.                 rescopy := res;
  219.                 if HandToHand(rescopy) <> noErr then
  220.                     Barf; {instead of DetachResource(res);}
  221.                 CheckError;
  222.                 AddResource(rescopy, theResType, id, theName);
  223.                 CheckError;
  224.                 ReleaseResource(rescopy);
  225.                 if not wasLoaded then
  226.                     ReleaseResource(res); {If it wasn't loaded, we don't leave it loaded.}
  227.                 CheckError;
  228.                 CopyResource := noErr;
  229.             end
  230.         else
  231.             begin
  232.                 CopyResource := resNotFound;
  233.             end;
  234.         UseResFile(oldResFile);
  235.     end; {CopyResource}
  236.  
  237. end.